﻿define(function(require, exports, module) {
	$.fn.J_linkage = function(options) {
        var opts;
        var DATA_NAME = "J_linkage";
        //返回API
        if (typeof options == "string") {
            if (options == "api") {
                return $(this).data(DATA_NAME);
            }
        } else {
            var options = options || {};
            //覆盖参数
            opts = $.extend(true, {}, $.fn.J_linkage.defaults, options);
        }
        if ($(this).size() > 0) {
            var J_linkage = new selectjs.Linkage(opts);
            J_linkage.$applyTo = $(this);
            J_linkage.render();
            $(this).data(DATA_NAME, J_linkage);
        }
        return $(this);
    };
    var selectjs = selectjs || {};
    selectjs.Linkage = function(options) {
        //参数
        this.options = options;
        //起作用的对象
        this.$applyTo = this.options.applyTo && $(this.options.applyTo) || null;
        //缓存前缀
        this.cachePrefix = "data_";
        //写入到选择框的option的样式名	
        this.OPTIONS_CLASS = "seclect-option";
        //缓存，为一个对象字面量。 
        this.cache = {};
    };
    selectjs.Linkage.prototype = {
        /**
		 * 运行
		 * @return {Object} this
		 */
        render:function() {
            var _that = this;
			var _opts = this.options;
            if (this.$applyTo != null && this.size() > 0) {
                _opts.style != null && this.css(_opts.style);
                //加载默认数据，向第一个选择框填充数据
				if (_opts.texts.length > 0){
				  this.selected(_opts.texts);
				}else{
				  this.load(_opts.defaultLoadSelectIndex, _opts.defaultParentId);
				}
				 
				//给每个选择框绑定change事件
                this.$applyTo.each(function(i) {
				 
                    i < _that.size() - 1 && $(this).find('.option li').live("click", {
                        target:_that,
                        index:i
                    }, _that.onchange);
                });
            }
            return this;
        },
        texts:function(ts) {
            var that = this;
            var $select = this.$applyTo;
            var _arr = [];
            var txt = null;
            var $options;
            $select.each(function() {
                txt = $(this).children("." + that.OPTIONS_CLASS + ":selected").text();
                _arr.push(txt);
            });
            return _arr;
        },
        /**
		 * 获取联动选择框的数量
		 * @return {Number} 选择框的数量
		 */
        size:function() {
            return this.$applyTo.size();
        },
        /**
		 * 设置选择框的样式
		 * @param {Object} style 样式
		 * @return {Object} this
		 */
        css:function(style) {
            style && this.$applyTo.css(style);
            return this;
        },
        /**
		 * 读取数据，并写入到选择框
		 * @param {Number} selectIndex 选择框数组的索引值
		 * @param {String} parentid  父级id
		 */
        load:function(selectIndex, parentid, callback) {
		
			   
            var _that = this;
            //清理index以下的选择框的选项
            for (var i = selectIndex; i < _that.size(); i++) {
                _that.removeOptions(i);
            }
			
            //存在缓存数据,直接使用缓存数据生成选择框的子项；不存在，则请求数据
            if (_that.cache[parentid]) {
			  
                _that._create(_that.cache[parentid], selectIndex);
                _that.$applyTo.eq(selectIndex).trigger("afterLoad");
                if (callback) callback.call(this);
            } else {
                //如果存在指定数据源，从指定的数据源中查询数据，否则AJAX查询
                if (this.options.data!=null) {
				
				    var cachedata = this.options.data;
					var aStr = [];
					var optionClass = _that.OPTIONS_CLASS;
                    $.each(cachedata, function(i) {
					
					    if (cachedata[i][_that.options.field["parentid"]] == parentid) {
						   aStr.push(this);
                        }
                    });
					
					var newaStr = {'data':aStr};
					var _h = _that._getOptionsHtml(newaStr);
					_that._create(_h, selectIndex);
                    _that.cache[parentid] = _h;
                    _that.$applyTo.eq(selectIndex).trigger("afterLoad.J_linkage");
					if (callback) callback.call(this);
				} else {

                    var _ajaxOptions = this.options.ajaxOptions;
                    var _d = _ajaxOptions.data;
                    var _parentIdField = this.options.field["parentid"];
                    _d[_parentIdField] = parentid;
                    //传递给后台的参数
                    _ajaxOptions.data = _d;
                    //ajax获取数据成功后的回调函数
                    _ajaxOptions.success = function(data) {
                        //遍历数据，获取html字符串
						
						
                        var _h = _that._getOptionsHtml(data);
						
                        _that._create(_h, selectIndex);
						
                        _that.cache[parentid] = _h;
						
                        _that.$applyTo.eq(selectIndex).trigger("afterLoad.J_linkage");
						
                        if (callback) callback.call(this);
                    };
                    $.ajax(_ajaxOptions);
                }
            }
        },
        /**
		 * 删除指定index索引值的选择框下的选择项
		 * @param {Number} index 选择框的索引值
		 * @return {Object} this
		 */
        removeOptions:function(index) {
		    this.$applyTo.eq(index).find('.checked').attr('style','');
			this.$applyTo.eq(index).find('.option ul').attr('style','');
			
			this.$applyTo.eq(index).find('.checked span').text(this.$applyTo.eq(index).find('.checked span').attr('title'));
            this.$applyTo.eq(index).find("." + this.OPTIONS_CLASS).remove();
            return this;
        },
        selected:function(t, completeCallBack) {
		
            var _that = this;
            if (t && typeof t == "object" && t.length > 0) {
			    var $select = this.$applyTo;
                _load(_that.options.defaultLoadSelectIndex, _that.options.defaultParentId);
            }
            /**
			 * 递归获取选择框数据
			 * @param {Number} selectIndex 选择框的索引值
			 * @param {Number} parentid   id
			 */
            function _load(selectIndex, parentid) {
			    _that.load(selectIndex, parentid, function() {
                    var id = _selected(selectIndex, t[selectIndex]);
                    selectIndex++;
                    if (selectIndex > _that.size() - 1) {
                        if (completeCallBack) completeCallBack.call(this);
                        return;
                    }
                    _load(selectIndex, id);
                });
            }
            /**
			 * 选中包含指定文本的选择项
			 * @param {Number} index 选择框的索引值
			 * @param {String} text  文本
			 * @return {Number} 该选择框的value值
			 */
            function _selected(index, text) {
			    
                var id = 0;
                _that.$applyTo.eq(index).find('li').each(function() {
                    if ($(this).attr('data')==text) {
					    var select = $(this).parents('.J_select');
					    $(this).addClass('here');
		                select.find('.checked span').text($(this).text());
					    id = $(this).attr('data');
                        return;
                    }
                });
                return id;
            }
            return this;
        },
        /**
		 * 选择框的值改变后触发的事件
		 * @param {Object} e 事件
		 */
        onchange:function(e) {
		
		    
            //实例化后的对象引用
            var _this = e.data.target;
            //选择框的索引值
            var index = e.data.index;
            //目标选择框
            var $target = $(e.target);
			var _parentId = $target.attr('data');
            var _i = index + 1;
			var select = $target.parents('.J_select'),
		          text = $target.text();
		    select.find('.option .here').removeClass('here');
		    $target.addClass('here');
		    select.find('.checked span').text(text);
			if (_this.options.target){
			 _this.options.target.val(_parentId);
			}else{
			 select.find('input').val(_parentId);
			}
			
		    
		    select.removeClass('J_select_hover');
			
			_this.load(_i, _parentId);
        },
        /**
		 * 将数据源（json或xml）转成html
		 * @param {Object} data
		 * @return {String} html代码字符串
		 */
        _getOptionsHtml:function(data) {
		
            var _that = this;
            var ajaxOptions = this.options.ajaxOptions;
            var field = this.options.field;
            var _h = "";
            _h = _getOptions(data, field).join("");
            /**
			 * 获取选择框项html代码数组
			 * @param {Object | Array} data 数据
			 * @param {Object} field 字段
			 * @return {Array} aStr 
			 */
            function _getOptions(data, field) {
                var optionClass = _that.OPTIONS_CLASS;
                var aStr = [];
                var id, name;
                $.each(data.data, function(i) {
                    id = data.data[i][field.id];
                    name = data.data[i][field.name];
                    var _option = "<li data='" + id + "' class='" + optionClass + "'>" + name + "</li>";
                    aStr.push(_option);
                });
                return aStr;
            }
            return _h;
        },
        /**
		 * 向选择框添加html
		 * @param {String} _h html代码
		 * @param {Number} index 选择框的索引值
		 */
        _create:function(_h, index) {
            var _that = this;
			this.removeOptions(index);
            this.$applyTo.eq(index).find('.option ul').append(_h);
			
        }
    };
    $.fn.J_linkage.defaults = {
        /**选择框对象数组*/
        selects:null,
        /**ajax配置*/
        ajaxOptions:{
            url:null,
            type:"get",
            data:{},
            success:function() {},
            beforeSend:function() {}
        },
        /**默认父级id*/
        defaultParentId:0,
        /**默认读取数据的选择框*/
        defaultLoadSelectIndex:0,
        /**将值写入到指定的元素中*/
        target:"",
        /**默认选择框中的选中项*/
        texts:[],
        /**选择框的样式*/
        style:null,
        /**选择框值改变时的回调函数*/
        change:function() {},
        field:{
            id:"id",
            name:"name",
            parentid:"parentid"
        },
        data:null
    };
});